#include "../SystemEventMonitor.h"
#include "../TcpSocket.h"
#include "../TcpAcceptor.h"

#include <stdio.h>
#include <string>

using namespace Greatewall::Interface;
using namespace Greatewall::Network;

class TestEvent : public SystemEventMonitor::TimerEvent
{
public:
    TestEvent(timespec& interval, bool periodic, TimerEventManagerBase& manager, std::string msg)
        : SystemEventMonitor::TimerEvent(interval, periodic, manager)
        , _msg(msg)
    {}

    virtual void
    triggered()
    { printf("%s[%ld]:%s...\n", _timer_event_manager.getTimeStamp(), _timer_event_manager.getNumberOfEvents(),  _msg.c_str()); }

private:
    std::string _msg;
};

class TestTcpSocket : public TcpSocket
{
public:
    TestTcpSocket(SocketEventMonitor& monitor)
        : TcpSocket(monitor)
    {}

    virtual ~TestTcpSocket()
    {
        printf("Destroy TestTcpSocket\n");
    }

    virtual void
    handleInbound()
    {
        char* buf = 0;
        ssize_t size = 0;
        if (!recv(buf, size))
        {
            printf("Unable to receive message!\n");
        }
        else
        {
            if (size > 0)
            {
                printf("Recv buff %p size %d\n", buf, size);
                dump(buf, size);
                send(buf, size);
            }
            else
            {
                printf("Disconnected... clean up\n");
                delete this;
            }
        }
    }

    virtual bool
    handleOutbound()
    { return true; }

private:
    void
    dump(const char* buf, ssize_t size)
    {
        const char* end = buf+size;
        for(int i = 0; buf+i < end; ++i)
        {
            if (i % 16 == 0)
                printf("[%04d]: ", i);

            printf("%02X", buf[i]);

            if (i && (i+1) % 4 == 0)
                printf(" ");

            if (i && (i+1) % 16 == 0)
                printf("\n");
        }
        printf("\n");
    }
};

class TestTcpAcceptor : public TcpAcceptor
{
public:
    TestTcpAcceptor(SocketEventMonitor& sock_event_monitor)
        : TcpAcceptor(sock_event_monitor)
    {}

    virtual SystemSocket*
    createClientHandler(SysSockHandler hdl, std::string host, short port)
    {
        TestTcpSocket* sock = new TestTcpSocket(_sock_event_monitor);
        sock->initTcpSock(hdl, host, port);
        return sock;
    }
};

int main()
{
    SystemEventMonitor system_event_monitor;

    timespec interval;
    interval.tv_sec  = 1;
    interval.tv_nsec = 0;

    TestEvent event1(interval, true, system_event_monitor.getTimerEventManager(), "Event 1...");

    interval.tv_sec  = 1;
    interval.tv_nsec = 1000000000/2;
    TestEvent event2(interval, true, system_event_monitor.getTimerEventManager(), "Event 2...");

    interval.tv_sec  = 1;
    interval.tv_nsec = 1000000000/4;
    TestEvent event3(interval, true, system_event_monitor.getTimerEventManager(), "Event 3...");

    interval.tv_sec  = 1;
    interval.tv_nsec = 1000000000/5;
    TestEvent event4(interval, true, system_event_monitor.getTimerEventManager(), "Event 4...");

    interval.tv_sec  = 1;
    interval.tv_nsec = 1000000000/10;
    TestEvent event5(interval, false, system_event_monitor.getTimerEventManager(), "Event 5...");

    //event1.start();
    //event2.start();
    //event3.start();
    //event4.start();
    //event5.start();

    TestTcpAcceptor acceptor(system_event_monitor);
    acceptor.initTcpAcceptor(12999, "");

    system_event_monitor.run();
}
